import { CSSProperties, ReactNode, useRef, useState, useEffect } from "react"

interface MyLazyLoadProps {
    className?: string
    style?: CSSProperties
    placeholder?: ReactNode
    offset?: string | number
    width?: number | string
    height?: number | string
    onContentVisible?: () => void
    children: ReactNode
}

export const MyLazyLoad: React.FC<MyLazyLoadProps> = (props) => {
    const {
        className = '',
        style,
        offset = 0,
        width,
        onContentVisible,
        placeholder,
        height,
        children
    } = props;
    const containerRef = useRef<HTMLDivElement>(null)
    const elementObserver = useRef<IntersectionObserver>()
    const [visible, setVisible] = useState(false)
    const styles = { height, width, ...style };

    const lazyloadHandler = (entries: IntersectionObserverEntry[]) => {
        const [entry] = entries
        const { isIntersecting } = entry
        if (isIntersecting) {
            setVisible(true)
            onContentVisible?.()
            const node = containerRef.current;
            if (node && node instanceof HTMLElement) {
                elementObserver.current?.unobserve(node);
            }
        }
    }
    useEffect(() => {
        const options = {
            rootMargin: typeof offset === 'number' ? `${offset}px` : offset || '0px',
            threshold: 0
        }
        elementObserver.current = new IntersectionObserver(lazyloadHandler, options)
        const node = containerRef.current
        if (node instanceof HTMLElement) {
            elementObserver.current.observe(node)
        }
        return () => {
            if (node && node instanceof HTMLElement) {
                elementObserver.current?.unobserve(node)
            }
        };
    }, []);

    return <div ref={containerRef} className={className} style={styles}>
        {visible ? children : placeholder}
    </div>
}